#include <numeric>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
using namespace std;
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
#define Rep(i,n) for(int i=0;i<(n);++i) 
#define For(i,a,b) for(int i=(a);i<=(b);++i) 
#define ForI(TP,i,coll) for(TP (i)=coll.begin();(i)!=coll.end();(i)++)
#define ForD(i,a,b) for(int i=(a);i>=(b);--i)
#define All(a) a.begin(), a.end()

struct PT{int x,y;
PT(int x=0, int y=0)
:x(x),y(y){}
};
ostream& operator<<(ostream& o, const PT& p)
{
	o<<"("<<p.x<<","<<p.y<<")";
	return o;
}
typedef vector<PT> VPT;
bool operator==(const PT& p1, const PT& p2)
{
	return p1.x==p2.x && p1.y==p2.y;
}
PT c;

int dist(const PT& p1, const PT& p2)
{
	return abs(p1.x-p2.x)+abs(p1.y-p2.y);
}

bool near_company(const PT& p1, const PT& p2) // sort use the distance to company
{
	return dist(p1, c)<dist(p2, c);
}

bool between(int i1, int i2, int i)
{
	return i1<=i2 ? (i>=i1 && i<=i2)
		: between(i2, i1, i);
}
bool between(const PT& p1, const PT& p2, const PT& p)
{
	return between(p1.x, p2.x, p.x) && between(p1.y, p2.y, p.y);
}

int N;
vector<PT> emps;

int dist(vector<PT>& car)
{
	if(car.empty()) return 0;

	sort(car.begin(), car.end(), near_company);
	int ret=dist(c, car.front());
	Rep(i, car.size()-1)
		ret+=dist(car[i], car[i+1]);
	return ret;
}

VPT::iterator find_nearest(VPT& emp_l, const VPT& car)
{
	VPT::iterator it_get=emp_l.end();
	int dmin=99999999;

	for(VPT::iterator it=emp_l.begin(); it!=emp_l.end(); it++)
	{
		int ndmin=99999999;
		Rep(i, car.size())
			ndmin=min(ndmin, dist(car[i], *it));

		if(ndmin<dmin)
		{
			it_get=it;
			dmin=ndmin;
		}
	}
	return it_get;
}

bool should_add(VPT car, PT p)
{
	int dold=dist(car) + dist(c, p);
	car.push_back(p);
	int dn=dist(car);
	return (dn<dold);
}

void putpath(const PT& p1, const PT& p2)
{
	PT p=p1;
	while(p.x!=p2.x)
	{
		cout<<" "<<p;
		p.x+=
			p.x<p2.x ? 1 : -1;
	}
	while(p.y!=p2.y)
	{
		cout<<" "<<p;
		p.y+=
			p.y<p2.y ? 1:-1;
	}
}
void putpath(VPT& car)
{
	putpath(c, car.front());
	Rep(i, car.size()-1)
		putpath(car[i], car[i+1]);
	cout<< " "<<car.back();
}

int main()
{
	cin>>N;
	Rep(i,N)
	{
		PT p;
		cin>>p.x>>p.y;
		emps.push_back(p);
	}
	cin>>c.x>>c.y;

	//
	for(int i=0;i<emps.size();)
	{
		if(emps[i]==c)
			emps.erase(emps.begin()+i);
		else
			i++;
	}

	sort(emps.begin(), emps.end(), near_company);

	//
	vector<VPT> cars;
	while(!emps.empty())
	{
		vector<PT> car;
		car.push_back(emps.back());

		emps.pop_back();

		for(int i=emps.size()-1;i>=0 && car.size()<4; i--)
		{
			if(between(car.back(), c, emps[i]))
			{
				car.push_back(emps[i]);
				emps.erase(emps.begin()+i);
			}
		}

		//
		while(car.size()<4 && !emps.empty())
		{
			VPT::iterator it_n= find_nearest(emps, car);
			if(it_n==emps.end())
				break;
			if(!should_add(car, *it_n))
				break;

			car.push_back(*it_n);
			emps.erase(it_n);
		}

		// output
		cars.push_back(car);
	}

	// output
	int ndist=0;
	VI res(cars.size());
	Rep(i, cars.size())
	{
		res[i]=dist(cars[i]);
	}

	cout<< accumulate(All(res), 0) <<endl;
	cout<<cars.size()<<endl;

	Rep(i, cars.size())
	{
		
		VPT& car=cars[i];
		cout<< res[i] << " ";
		Rep(i, car.size())
			cout<< "("<<car[i].x<<","<<car[i].y<<") ";
		cout<< ":";
		putpath(car);

		cout<< endl;
	}

}